#include "Assignment2.h"

#include <SDL/SDL_image.h>
#include <SDL/SDL_mixer.h>
#include <iostream>
/*
================================
Assignment2::Instance

Singleton pattern.
================================
*/
State* Assignment2::Instance()
{
	static Assignment2 the_Assignment2;
	return &the_Assignment2;
}

/*
================================
Assignment2::Assignment2
================================
*/
Assignment2::Assignment2()
{
	
}

//Ogre::Entity* ogreHead;
//Ogre::SceneNode* headNode;
Ogre::Vector3 pos;

Ogre::SceneManager* sm;

Paddle::Paddle( const char* name )
{
	en = sm->createEntity( name, "ogrehead.mesh" );
	sn = sm->getRootSceneNode()->createChildSceneNode();
	sn->attachObject( en );
	pos = Ogre::Vector3( 0, 0, 0 );
	vel = Ogre::Vector3( 0, 0, 0 );
}

Paddle::~Paddle()
{
	
}

void Paddle::input( const InputSet& is )
{
	if ( is.get( IS_U ) )
		pos.y += 2;
	if ( is.get( IS_D ) )
		pos.y -= 2;
	if ( is.get( IS_L ) )
		pos.x -= 2;
	if ( is.get( IS_R ) )
		pos.x += 2;
}

void Paddle::update()
{
	pos += vel;

	sn->setPosition( pos );
}

/*
================================
Assignment2::init
================================
*/
void Assignment2::init( Engine* game )
{
	server = game->server;
	client = game->client;
	isServer = game->isServer;
	
	frames_elapsed = 0;

	sm = game->root->createSceneManager( "DefaultSceneManager" );
	Ogre::Camera* cam = sm->createCamera( "PlayerCam" );
	if(isServer){
		cam->setPosition( Ogre::Vector3( 0, 0, 3100 ) );
		cam->lookAt( Ogre::Vector3( 0, 0, -300 ) );
	}
	else{
		cam->setPosition( Ogre::Vector3( 0, 0, -3100 ) );
		cam->lookAt( Ogre::Vector3( 0, 0, 300 ) );
	}
	cam->setNearClipDistance( 5 );

	Ogre::Viewport* vp = game->window->addViewport( cam, 0 );
	vp->setBackgroundColour( Ogre::ColourValue( 0, 0, 0 ) );
	cam->setAspectRatio(
		Ogre::Real( vp->getActualWidth() ) /
		Ogre::Real( vp->getActualHeight() ) );

	//ogreHead = sm->createEntity( "Head", "ogrehead.mesh" );
	//headNode = sm->getRootSceneNode()->createChildSceneNode();
	//headNode->attachObject( ogreHead );
	sm->setAmbientLight( Ogre::ColourValue( 0.5, 0.5, 0.5 ) );
	Ogre::Light* l = sm->createLight( "MainLight" );
	l->setPosition( 0, 0, 4000 );
	Ogre::Light* l2 = sm->createLight( "SubLight" );
	l2->setPosition( 0, 0, -4000);

	pos = Ogre::Vector3( 0, 0, 0 );

	// Paddles
	//a = new Paddle( "a" );
	//b = new Paddle( "b" );
	
	field = new PlayingField("field", sm, sm->getRootSceneNode());
	
	Ogre::SceneNode* player1Node = sm->getRootSceneNode()->createChildSceneNode();
	player1Node->setPosition(0,0,1300);
	player1V = new ClientRiotShield("player1",sm,player1Node,1);
	client->addTarget(1, player1V);
	
	Ogre::SceneNode* player2Node = sm->getRootSceneNode()->createChildSceneNode();
	player2Node->setPosition(0,0,-1300);
	player2V = new ClientRiotShield("player2",sm,player2Node,2);
	client->addTarget(2, player2V);
	
	controlRes = new ClientControlResponder(client, isServer ? 1 : 2, isServer ? 1 : 0);
	
	Ogre::SceneNode* score1Node = sm->getRootSceneNode()->createChildSceneNode();
	Ogre::SceneNode* score2Node = sm->getRootSceneNode()->createChildSceneNode();
	if(isServer){
		score1Node->setPosition(-300,600,1450);
		score2Node->setPosition(300,600,1450);
	}
	else{
		score1Node->yaw(Ogre::Degree(180));
		score2Node->yaw(Ogre::Degree(180));
		score1Node->setPosition(-300,600,-1450);
		score2Node->setPosition(300,600,-1450);
	}
	score1V = new ClientScoreCard("p1Score", sm, score1Node);
	client->addTarget(3, score1V);
	score2V = new ClientScoreCard("p2Score", sm, score2Node);
	client->addTarget(4, score2V);
	
	grenadeV = new ClientFlashBang("grenade", sm, sm->getRootSceneNode());
	client->addTarget(5, grenadeV);
	
	if(isServer){
		player1 = new ServerRiotShield("player1", sm, player1Node, server, 1, 1);
		server->addTarget(1, player1);
		
		player2 = new ServerRiotShield("player2", sm, player2Node, server, 2, 2);
		server->addTarget(2, player2);
		
		score1 = new ServerScoreCard(server, 3);
		
		score2 = new ServerScoreCard(server, 4);
		
		grenade = new ServerFlashBang(score1, player1, score2, player2, server, 5);
	}
	/*
	Ogre::SceneNode* scoreNode = playerNode->createChildSceneNode();
	scoreNode->setPosition(100,600,150);
	score = new ScoreCard("score", sm, scoreNode);
	
	grenade = new FlashBang("grenade", sm, sm->getRootSceneNode(), score, player);
	*/
}

/*
================================
Assignment2::cleanup
================================
*/
void Assignment2::cleanup( Engine* game )
{
	// TODO: Is this all the cleanup we need for OGRE?
	game->window->removeViewport( 0 );
	game->root->destroySceneManager( sm );
}

/*
================================
Assignment2::input
================================
*/
void Assignment2::input( Engine* game )
{
	//a->input( game->is1 );
	//b->input( game->is2 );
	//player->alertToInput( game->is1 );
	field->alertToInput( game->is1 );
	//grenade->alertToInput( game->is1 );
	player1V->alertToInput( game->is1 );
	player2V->alertToInput( game->is1 );
	controlRes->alertToInput( game->is1 );
	grenadeV->alertToInput( game->is1 );
	if(isServer){
		player1->alertToInput( game->is1 );
		player2->alertToInput( game->is1 );
	}
}

/*
================================
Assignment2::update
================================
*/
void Assignment2::update( Engine* game )
{
	frames_elapsed++;
	//a->update();
	//b->update();
	//player->updateState();
	//score->updateState();
	//grenade->updateState();
	//headNode->setPosition( pos );
	player1V->updateState();
	player2V->updateState();
	controlRes->updateState();
	grenadeV->updateState();
	if(isServer){
		player1->updateState();
		player2->updateState();
		score1->updateState();
		score2->updateState();
		grenade->updateState();
	}
	client->broadcastMessages();
	if(isServer){
		server->broadcastMessages();
	}
}

/*
================================
Assignment2::draw
================================
*/
void Assignment2::draw( Engine* game )
{
	//score->draw(game);
}

/*
================================
Assignment2::setCaption
================================
*/
void Assignment2::setCaption( std::ostringstream& buffer )
{
	buffer << " || Assignment2:";
	buffer << " " << frames_elapsed << " frames elapsed";
}

